package dao

import (
	"fmt"
	"yundian/internel/app/dao/memberdao"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/membermodel"
	"yundian/internel/app/models/orders"
	"yundian/internel/app/models/reports"
	"yundian/internel/app/models/users"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
)

// -------------------- dao层 - 故障相关操作 -----------------------//

type ReportDao struct {
}

func NewReportDao() *ReportDao {
	return &ReportDao{}
}

func (d *ReportDao) StewardStatisticsAllNum(param *request.StewardStatisticsReq) *dingo.ErrorWrap {
	var lst []*request.StewardStatisticsRes
	db := global.Orm.Table("place_reports pr").Select("10 type,COUNT(1)num")

	if param.IsAdmin != helper.TypeNumIsAdminOperator {
		db.Joins("LEFT JOIN places p ON p.id=pr.place_id")
		db.Where("p.user_id=?", param.LoginUserId)
	}

	if param.Status == 5 {
		db.Where("pr.status=?", 1)
	}
	if param.Status == 6 {
		db.Where("pr.status=?", 2)
	}
	if param.Status > 6 {
		db.Where("pr.status>=?", 3)
	}
	if param.PlaceId > 0 {
		db.Where("pr.place_id=?", param.PlaceId)
	}
	if param.StartTime != "" {
		db.Where("pr.create_time>=?", param.StartTime)
	}
	if param.EndTime != "" {
		db.Where("pr.create_time<=?", param.EndTime)
	}

	db.Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *ReportDao) StewardStatisticsComplaint(param *request.StewardStatisticsReq) *dingo.ErrorWrap {
	var lst []*request.StewardStatisticsRes
	db := global.Orm.Table("place_reports pr").Select("type,COUNT(1)num")

	if param.IsAdmin != helper.TypeNumIsAdminOperator {
		db.Joins("LEFT JOIN places p ON p.id=pr.place_id")
		db.Where("p.user_id=?", param.LoginUserId)
	}

	if param.Status > 0 {
		db.Where("pr.status=?", param.Status)
	}
	if param.PlaceId > 0 {
		db.Where("pr.place_id=?", param.PlaceId)
	}
	if param.StartTime != "" {
		db.Where("pr.create_time>=?", param.StartTime)
	}
	if param.EndTime != "" {
		db.Where("pr.create_time<=?", param.EndTime)
	}

	db.Group("type").Order("num DESC").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *ReportDao) SetAdminPlaceReportStatus(param *request.GetPlaceReportsListReq) *dingo.ErrorWrap {
	db := global.Orm.Table("place_reports").Where("id=?", param.Id).Update("status", param.Status)
	return dingo.ErrorIf(db.Error)
}

func (d *ReportDao) GetAdminPlaceReportDetails(param *request.GetPlaceReportsListReq) *dingo.ErrorWrap {
	dataInfo := &request.GetPlaceReportsDetailsReq{}

	field := `pr.id,member_id,place_id,device_sn,img_paths,type,pr.status,room,p.place_name,pr.address,pr.desc,m.nick_name, 
	m.phone,DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("place_reports pr").Select(field)
	db.Joins("LEFT JOIN places p ON pr.place_id=p.id")
	db.Joins("LEFT JOIN members m ON m.id=pr.member_id")
	db.Where("pr.id=?", param.Id)

	if param.IsAdmin != helper.TypeNumIsAdminOperator {
		db.Where("p.user_id=?", param.LoginUserId)
	}

	db.Find(&dataInfo)

	return dingo.ErrorIf(db.Error, dataInfo)
}

func (d *ReportDao) GetAdminPlaceReportList(param *request.GetPlaceReportsListReq) *dingo.ErrorWrap {

	var (
		lst    []*reports.PlaceReportsModel
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	field := `pr.id,member_id,place_id,device_sn,img_paths,type,pr.status,room,p.place_name,pr.address,pr.desc, 
	DATE_FORMAT(create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("place_reports pr").Select(field)
	db.Joins("LEFT JOIN places p ON pr.place_id=p.id")

	if param.IsAdmin != helper.TypeNumIsAdminOperator {
		db.Where("p.user_id=?", param.LoginUserId)
	}

	if param.DeviceSn != "" {
		db.Where("pr.device_sn=?", param.DeviceSn)
	}
	if param.Status > 0 {
		db.Where("pr.status=?", param.Status)
	}
	if param.PlaceId > 0 {
		db.Where("pr.place_id=?", param.PlaceId)
	}

	db.Order("pr.id desc")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// InsertPlaceReport 新增
func (d *ReportDao) InsertPlaceReport(m *request.InsertPlaceReportReq) *dingo.ErrorWrap {
	db := global.Orm.Create(&m)
	return dingo.ErrorIf(db.Error, true)
}

// InsertReport 新增
func (d *ReportDao) InsertReport(m *reports.ReportsModel) *dingo.ErrorWrap {
	db := global.Orm.Table("reports").Create(m)
	return dingo.ErrorIf(db.Error, true)
}

// InsertReport 新增
func (d *ReportDao) InsertAliPayReport(m *reports.ReportsModel) *dingo.ErrorWrap {
	db := global.Orm.Table("reports").Create(m)
	return dingo.ErrorIf(db.Error, true)
}

// GetOrderList 获取网点列表API
func (d *ReportDao) GetReportList(param *request.ReportListReq) *dingo.ErrorWrap {

	var (
		lst    []*reports.ReportList
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)
	fields := `r.*, d.prod_type`
	db := global.Orm.Table("reports r").Select(fields)
	db.Joins("LEFT JOIN devices d ON r.device_sn = d.device_sn")
	if param.TradeNo != "" { // 订单编号
		db.Where("r.trade_no = ?", param.TradeNo)
	}
	if param.PlaceName != "" { // 查询条件：网点名称
		db.Where("r.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	}
	if param.Status > 0 { // 查询条件：状态
		db.Where("r.status = ?", param.Status)
	}
	if param.StartTime > 0 && param.EndTime > 0 { // 查询条件：创建时间
		db.Where("r.create_at >= ? and r.create_at<= ?", param.StartTime, param.EndTime)
	}

	if param.ProdType > 0 {
		db.Where("d.prod_type = ?", param.ProdType)
	}

	// 排序
	db.Order("r.create_at desc")

	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// GetReportDetail 获取定单详情
func GetReportDetail(orderId int) *dingo.ErrorWrap {
	var (
		reportDetail reports.ReportDetail
	)
	sql := "select m.nick_name as nickName,r.* from reports r LEFT JOIN members m on r.member_id = m.id where r.id = ?"
	db := global.Orm.Raw(sql, orderId).Find(&reportDetail)

	// 所属代理 名称
	puserName := NewUserDao().GetUserByPlaceId(reportDetail.PlaceId).Unwrap().(*users.UserModel).UserName
	reportDetail.PuserName = puserName

	//报修用户名 NickName
	nickName := memberdao.NewMemberDao().GetMemberInfoById(reportDetail.MemberId).Unwrap().(*membermodel.MembersModel).NickName
	reportDetail.NickName = nickName

	//订单信息
	OrderModel := NewOrderDao().GetOrderInfoByTradeNo(reportDetail.TradeNo).Unwrap().(*orders.OrderModel)
	reportDetail.Money = OrderModel.Money
	reportDetail.OrderCreateAt = OrderModel.CreateAt
	reportDetail.PayFrom = OrderModel.PayFrom
	reportDetail.OrderStatus = OrderModel.State

	// 设备信息
	deviceType := NewDeviceDao().FetchDeviceInfoWithType(reportDetail.DeviceSn).Unwrap().(*devices.DeviceType)
	reportDetail.DeviceModelId = deviceType.DeviceModelId
	reportDetail.DeviceName = deviceType.DeviceName
	reportDetail.DeviceCreateAt = deviceType.CreateAt

	return dingo.ErrorIf(db.Error, reportDetail)
}

// UpdateReport 获取定单详情
func UpdateReport(orderId int, reportDesc string) *dingo.ErrorWrap {

	sql := "UPDATE reports SET status = 2, report_desc = ? WHERE id = ?"
	db := global.Orm.Exec(sql, reportDesc, orderId)

	return dingo.ErrorIf(db.Error, true)
}
